//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <mantle.h>

// Interface functions
//
PInterface CCondition::Probe(
    /* [in] */ REIID riid)
{
    if (riid == EIID_IInterface) {
        return (PInterface)(ICondition *)this;
    }
    else if (riid == EIID_ICondition) {
        return (ICondition *)this;
    }
    else if (riid == EIID_CLASS_INFO) {
        return (PInterface)&ECLSID_CCondition;
    }
    else if (riid == EIID_INTERFACE_INFO) {
        return (PInterface)&EIID_ICondition;
    }
    return NULL;
}

UInt32 CCondition::AddRef(void)
{
    return (UInt32)m_cRef.Increment();
}

UInt32 CCondition::Release(void)
{
    Int32 nRef = m_cRef.Decrement();

    if (nRef == 0) {
        delete this;
    }
    return (UInt32)nRef;
}

ECode CCondition::Aggregate(
    /* [in] */ AggregateType type,
    /* [in] */ PInterface pObj)
{
    return E_NOT_IMPLEMENTED;
}

ECode CCondition::GetDomain(
    /* [out] */ PInterface *ppObj)
{
    return E_NOT_IMPLEMENTED;
}

ECode CCondition::Wait(
    /* [in] */ IMutex *pMutex,
    /* [out] */ WaitResult *pResult)
{
    if (NULL == pMutex || NULL == pResult) return E_INVALID_ARGUMENT;

    register DzMutex *pKMutex = &((CMutex*)pMutex)->m_kmutex;

    if (!pKMutex->IsHeld()) return E_NOT_OWNER;

    if (!pKMutex->IsHeldOnce()) return E_INVALID_OPERATION;

    m_kcondition.Wait(pKMutex, pResult);
    return NOERROR;
}

ECode CCondition::TryWait(
    /* [in] */ IMutex *pMutex,
    /* [in] */ Millisecond32 msTimeout,
    /* [out] */ WaitResult *pResult)
{
    if (NULL == pMutex || 0 >= msTimeout || NULL == pResult) {
        return E_INVALID_ARGUMENT;
    }

    register DzMutex *pKMutex = &((CMutex*)pMutex)->m_kmutex;

    if (!pKMutex->IsHeld()) return E_NOT_OWNER;

    if (!pKMutex->IsHeldOnce()) return E_INVALID_OPERATION;

    m_kcondition.TryWait(
                pKMutex, DzMillisecondsToTicks(msTimeout), pResult);
    return NOERROR;
}

ECode CCondition::Pulse()
{
    m_kcondition.Pulse();
    return NOERROR;
}

ECode CCondition::PulseAll()
{
    m_kcondition.PulseAll();
    return NOERROR;
}
